package vn.edu.hcmut.cse.ai.search.problems.blocksworld;

import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import vn.edu.hcmut.cse.ai.search.problems.blocksworld.predicate.BlocksWorldPredicate;
import vn.edu.hcmut.cse.ai.search.problems.blocksworld.predicate.*;

/**
 *
 * @author ngphi
 */
public class ReadInput {

    private int numBlock;
    private List<BlocksWorldPredicate> predicates = new ArrayList<>();
    private List<BlocksWorldPredicate> goal = new ArrayList<>();
    private BlocksWorldState initState;
    private BlocksWorldState goalState;

    public ReadInput() {

    }

    public void handle(String filename) {
        List<String> rowString = new ArrayList<String>();

        Path path = Paths.get(filename);
        try {
            rowString = Files.readAllLines(path, StandardCharsets.UTF_8);
        } catch (IOException e) {
            e.printStackTrace();
        }
        this.numBlock = Integer.parseInt(rowString.get(0));
        this.initState = new BlocksWorldState(numBlock);
        this.goalState = new BlocksWorldState(numBlock);
        List<BlocksWorldPredicate> predicates = new ArrayList<>();
        List<BlocksWorldPredicate> goalPredicates = new ArrayList<>();
        boolean start = true;
        boolean goal = false;
        for (int i = 1; i < rowString.size(); i++) {
            if (rowString.get(i).length() == 0) {
                i++;
                start = false;
                goal = true;
            }
            if (start) {
                if (rowString.get(i).contains("ON(")) {
                    String str = rowString.get(i);
                    str = str.replaceAll("[^0-9]+", " ");
                    List arr = Arrays.asList(str.trim().split(" "));
                    int b1 = Integer.valueOf(arr.get(0).toString());
                    int b2 = Integer.valueOf(arr.get(1).toString());
                    On on = new On(b1, b2);
                    predicates.add(on);
                }
                if (rowString.get(i).contains("ONT(")) {
                    String str = rowString.get(i);
                    str = str.replaceAll("[^0-9]+", " ");
                    List arr = Arrays.asList(str.trim().split(" "));
                    int b1 = Integer.valueOf(arr.get(0).toString());
                    OnTable ont = new OnTable(b1);
                    predicates.add(ont);
                }
                if (rowString.get(i).contains("CLEAR(")) {
                    String str = rowString.get(i);
                    str = str.replaceAll("[^0-9]+", " ");
                    List arr = Arrays.asList(str.trim().split(" "));
                    int b1 = Integer.valueOf(arr.get(0).toString());
                    Clear clear = new Clear(b1);
                    predicates.add(clear);
                }
                if (rowString.get(i).contains("ARMEMPTY")) {
                    ArmEmpty arm = new ArmEmpty();
                    predicates.add(arm);
                }
                if (rowString.get(i).contains("HOLDING(")) {
                    String str = rowString.get(i);
                    str = str.replaceAll("[^0-9]+", " ");
                    List arr = Arrays.asList(str.trim().split(" "));
                    int b1 = Integer.valueOf(arr.get(0).toString());
                    Holding hold = new Holding(b1);
                    predicates.add(hold);
                }
            }
            if (goal) {
                if (rowString.get(i).contains("ON(")) {
                    String str = rowString.get(i);
                    str = str.replaceAll("[^0-9]+", " ");
                    List arr = Arrays.asList(str.trim().split(" "));
                    int b1 = Integer.valueOf(arr.get(0).toString());
                    int b2 = Integer.valueOf(arr.get(1).toString());
                    On on = new On(b1, b2);
                    goalPredicates.add(on);
                }
                if (rowString.get(i).contains("ONT(")) {
                    String str = rowString.get(i);
                    str = str.replaceAll("[^0-9]+", " ");
                    List arr = Arrays.asList(str.trim().split(" "));
                    int b1 = Integer.valueOf(arr.get(0).toString());
                    OnTable ont = new OnTable(b1);
                    goalPredicates.add(ont);
                }
                if (rowString.get(i).contains("CLEAR(")) {
                    String str = rowString.get(i);
                    str = str.replaceAll("[^0-9]+", " ");
                    List arr = Arrays.asList(str.trim().split(" "));
                    int b1 = Integer.valueOf(arr.get(0).toString());
                    Clear clear = new Clear(b1);
                    goalPredicates.add(clear);
                }
                if (rowString.get(i).contains("ARMEMPTY")) {
                    ArmEmpty arm = new ArmEmpty();
                    goalPredicates.add(arm);
                }
                if (rowString.get(i).contains("HOLDING(")) {
                    String str = rowString.get(i);
                    str = str.replaceAll("[^0-9]+", " ");
                    List arr = Arrays.asList(str.trim().split(" "));
                    int b1 = Integer.valueOf(arr.get(0).toString());
                    Holding hold = new Holding(b1);
                    goalPredicates.add(hold);
                }
            }

        }
        this.initState.insertPredicates(predicates);
        this.goalState.insertPredicates(goalPredicates);
    }

    public BlocksWorldState getInit() {
        return initState;
    }

    public BlocksWorldState getGoal() {
        return goalState;
    }
}
